/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.seata.serializer.protobuf.convertor;

import org.apache.seata.core.exception.TransactionExceptionCode;
import org.apache.seata.core.model.GlobalStatus;
import org.apache.seata.core.protocol.ResultCode;
import org.apache.seata.core.protocol.transaction.GlobalRollbackResponse;
import org.apache.seata.serializer.protobuf.generated.AbstractGlobalEndResponseProto;
import org.apache.seata.serializer.protobuf.generated.AbstractMessageProto;
import org.apache.seata.serializer.protobuf.generated.AbstractResultMessageProto;
import org.apache.seata.serializer.protobuf.generated.AbstractTransactionResponseProto;
import org.apache.seata.serializer.protobuf.generated.GlobalRollbackResponseProto;
import org.apache.seata.serializer.protobuf.generated.GlobalStatusProto;
import org.apache.seata.serializer.protobuf.generated.MessageTypeProto;
import org.apache.seata.serializer.protobuf.generated.ResultCodeProto;
import org.apache.seata.serializer.protobuf.generated.TransactionExceptionCodeProto;

public class GlobalRollbackResponseConvertor
        implements PbConvertor<GlobalRollbackResponse, GlobalRollbackResponseProto> {
    @Override
    public GlobalRollbackResponseProto convert2Proto(GlobalRollbackResponse globalRollbackResponse) {
        final short typeCode = globalRollbackResponse.getTypeCode();

        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder()
                .setMessageType(MessageTypeProto.forNumber(typeCode))
                .build();

        final String msg = globalRollbackResponse.getMsg();
        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder()
                .setMsg(msg == null ? "" : msg)
                .setResultCode(ResultCodeProto.valueOf(
                        globalRollbackResponse.getResultCode().name()))
                .setAbstractMessage(abstractMessage)
                .build();

        AbstractTransactionResponseProto abstractTransactionResponseProto =
                AbstractTransactionResponseProto.newBuilder()
                        .setAbstractResultMessage(abstractResultMessageProto)
                        .setTransactionExceptionCode(TransactionExceptionCodeProto.valueOf(globalRollbackResponse
                                .getTransactionExceptionCode()
                                .name()))
                        .build();

        AbstractGlobalEndResponseProto abstractGlobalEndResponseProto = AbstractGlobalEndResponseProto.newBuilder()
                .setAbstractTransactionResponse(abstractTransactionResponseProto)
                .setGlobalStatus(GlobalStatusProto.valueOf(
                        globalRollbackResponse.getGlobalStatus().name()))
                .build();

        GlobalRollbackResponseProto result = GlobalRollbackResponseProto.newBuilder()
                .setAbstractGlobalEndResponse(abstractGlobalEndResponseProto)
                .build();

        return result;
    }

    @Override
    public GlobalRollbackResponse convert2Model(GlobalRollbackResponseProto globalRollbackResponseProto) {
        GlobalRollbackResponse branchRegisterResponse = new GlobalRollbackResponse();
        final AbstractGlobalEndResponseProto abstractGlobalEndResponse =
                globalRollbackResponseProto.getAbstractGlobalEndResponse();
        AbstractTransactionResponseProto abstractResultMessage =
                abstractGlobalEndResponse.getAbstractTransactionResponse();
        branchRegisterResponse.setMsg(
                abstractResultMessage.getAbstractResultMessage().getMsg());
        branchRegisterResponse.setResultCode(ResultCode.valueOf(
                abstractResultMessage.getAbstractResultMessage().getResultCode().name()));
        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
                abstractResultMessage.getTransactionExceptionCode().name()));
        branchRegisterResponse.setGlobalStatus(
                GlobalStatus.valueOf(abstractGlobalEndResponse.getGlobalStatus().name()));

        return branchRegisterResponse;
    }
}
